package negocio;

import com.google.gson.Gson;
import dto.LoginToken;
import entidades.*;
import excepciones.FachadaException;
import java.util.List;
import javax.ejb.Stateful;
import persistencia.*;
import utils.Encripta;

/**
 *
 * @author Juan Leal
 */
@Stateful
public class FachadaNegocio implements FachadaNegocioRemote {

    private EmpresaFacadeRemote facadeEmpresa;
    private TaxiFacadeRemote facadeTaxi;
    private SolicitudFacadeRemote facadeSolicitud;
    private UsuarioFacadeRemote facadeUsuario;
    private static final String PASSPHRASE = "46066-50172-50284";

    public FachadaNegocio() {
        facadeEmpresa = new EmpresaFacade();
        facadeTaxi = new TaxiFacade();
        facadeSolicitud = new SolicitudFacade();
        facadeUsuario = new UsuarioFacade();
    }

    /* Empresas */
    @Override
    public boolean agregarEmpresa(Empresa empresa) throws FachadaException {
        try {
            return facadeEmpresa.agregar(empresa);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean editarEmpresa(Empresa empresa) throws FachadaException {
        try {
            return facadeEmpresa.editar(empresa);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean eliminarEmpresa(Empresa empresa) throws FachadaException {
        try {
            return facadeEmpresa.eliminar(empresa);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public Empresa buscarmpresa(Empresa empresa) throws FachadaException {
        try {
            return facadeEmpresa.buscar(empresa.getId());
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Empresa> buscarEmpresas(Usuario usuario) throws FachadaException {
        try {
            return facadeEmpresa.buscarUserName(usuario);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Empresa> listarEmpresas() throws FachadaException {
        try {
            return facadeEmpresa.listarTodos();
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    // Taxis
    @Override
    public boolean agregarTaxi(Taxi taxi) throws FachadaException {
        try {
            return facadeTaxi.agregar(taxi);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean editarTaxi(Taxi taxi) throws FachadaException {
        try {
            return facadeTaxi.editar(taxi);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean eliminarTaxi(Taxi taxi) throws FachadaException {
        try {
            return facadeTaxi.eliminar(taxi);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public Taxi buscar(Taxi taxi) throws FachadaException {
        try {
            return facadeTaxi.buscar(taxi.getNTaxi());
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Taxi> listarTaxis() throws FachadaException {
        try {
            return facadeTaxi.listarTodos();
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Taxi> listarTaxis(Empresa empresa) throws FachadaException {
        try {
            return facadeTaxi.buscarUserName(empresa);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    // Solicitudes
    @Override
    public boolean agregar(Solicitud solicitud) throws FachadaException {
        try {
            return facadeSolicitud.agregar(solicitud);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean editar(Solicitud solicitud) throws FachadaException {
        try {
            return facadeSolicitud.editar(solicitud);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public boolean elimina(Solicitud solicitud) throws FachadaException {
        try {
            return facadeSolicitud.eliminar(solicitud);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public Solicitud buscar(Solicitud solicitud) throws FachadaException {
        try {
            return facadeSolicitud.buscar(solicitud.getId());
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Solicitud> buscarSolicitud(Usuario usuario) throws FachadaException {
        try {
            return facadeSolicitud.buscarUserName(usuario);
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public List<Solicitud> listarSolicitudes() throws FachadaException {
        try {
            return facadeSolicitud.listarTodos();
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public String iniciarSesion(Usuario usuario) throws FachadaException {
        try {
            Usuario user = facadeUsuario.validaUsuario(usuario.getUsername(), usuario.getPassword());
            if (user != null) {
                LoginToken token = new LoginToken(user.getUsername(), user.getPassword(), user.getRol());
                Gson gson = new Gson();

                String json = gson.toJson(token);
                Encripta enc = new Encripta(PASSPHRASE);
                String result = enc.encrypt(json);

                return result;
            } else {
                return "null";
            }
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }

    @Override
    public void validaSesion(String tokenEnc, String[] roles) throws FachadaException {
        LoginToken tokenObj = null;
        Usuario user = null;

        // Lee datos
        try {
            Encripta enc = new Encripta(PASSPHRASE);
            String tokenDec = enc.decrypt(tokenEnc);

            Gson gson = new Gson();
            tokenObj = gson.fromJson(tokenDec, LoginToken.class);
            user = facadeUsuario.validaUsuario(tokenObj.getUsername(), tokenObj.getPassword());
        } catch (Exception e) {
            throw new FachadaException(e);
        }

        // Valida datos
        if (user == null) {
            throw new FachadaException("Nombre de usuario o contraseña invalido");
        } else {

            // Valida si el usuario tiene alguno de los roles solicitados
            for (String rol : roles) {
                if (rol.equalsIgnoreCase(tokenObj.getRol())) {
                    // Si encuentra el rol en la coleccion entonces es correcto
                    return;
                }
            }
            // En este punto no encontro el rol en la coleccion, lanza error
            throw new FachadaException("Acceso no autorizado");
        }
    }

    @Override
    public Usuario buscaUsuario(String username) throws FachadaException{
        try {
            Usuario usr = facadeUsuario.buscar(username);
            usr.setPassword("");
            return usr;
        } catch (Exception e) {
            throw new FachadaException(e);
        }
    }
}
